﻿using DTM.Core.Utils;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;

namespace DTM.Repository
{
    /// <summary>
    /// Class <see cref="UnitOfWork"/> declare unit of work.
    /// </summary>
    internal class UnitOfWork : IUnitOfWork, IDisposable
    {
        #region Fields

        private readonly DatabaseEntities _context;
        private bool _disposed = false;
        private DbContextTransaction _transaction = null;

        private IPlayerRepository _payers = null;

        #endregion Fields

        #region Properties

        /// <summary>
        /// Players repository.
        /// </summary>
        public IPlayerRepository Players
        {
            get
            {
                if (_payers == null)
                {
                    _payers = new PlayerRepository(_context);
                }
                return _payers;
            }
        }

        #endregion Properties

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="UnitOfWork"/> class.
        /// </summary>
        public UnitOfWork(DatabaseEntities entities)
        {
            Validate.NotNull<ArgumentNullException>(entities, "entities");

            _context = entities;
            _transaction = _context.Database.BeginTransaction();
        }

        #endregion Constructors

        #region Methods

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Commit changes
        /// </summary>
        public void Commit()
        {
            try
            {
                _context.SaveChanges();
                _transaction.Commit();
            }
            catch
            {
                _transaction.Rollback();
                throw;
            }
            finally
            {
                _transaction = _context.Database.BeginTransaction();
            }
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!this._disposed)
            {
                if (disposing)
                {
                    _transaction.Dispose();
                    _context.Dispose();

                    if (_payers != null)
                    {
                        _payers.Dispose();
                    }
                }
            }
            this._disposed = true;
        }

        #endregion Methods
    }
}